<template>
  <div class="ol-map" id="olMap"></div>
</template>

<script lang='ts' setup>
import {ref, reactive, toRefs, onMounted, nextTick, watch} from 'vue'
import Map from 'ol/Map'  // OpenLayers的主要类，用于创建和管理地图
import View from 'ol/View'  // OpenLayers的视图类，定义地图的视图属性
import {Tile as TileLayer} from 'ol/layer'  // OpenLayers的瓦片图层类
import {XYZ, OSM} from 'ol/source'  // OpenLayers的瓦片数据源，包括XYZ格式和OpenStreetMap专用的数据源
import {fromLonLat, toLonLat} from 'ol/proj'  // OpenLayers的投影转换函数，用于经纬度坐标和投影坐标之间的转换
import {
  defaults as defaultInteractions,
  DragRotateAndZoom,
} from 'ol/interaction'  // OpenLayers的交互类，包括默认的交互集合和特定的旋转缩放交互
import {defaults, FullScreen, MousePosition, ScaleLine} from 'ol/control'  // OpenLayers的控件类，包括默认的控件集合和特定的全屏、鼠标位置、比例尺控件
import Feature from 'ol/Feature'  // OpenLayers的要素类，表示地图上的一个对象或实体
import Point from 'ol/geom/Point'  // OpenLayers的点几何类，用于表示点状的地理数据
import {Vector as VectorLayer} from 'ol/layer'  // OpenLayers的矢量图层类，用于显示矢量数据
import {Vector as VectorSource} from 'ol/source'  // OpenLayers的矢量数据源类，用于管理和提供矢量数据
import LineString from 'ol/geom/LineString'  // OpenLayers的线几何类，用于表示线状的地理数据
import {Circle as CircleStyle, Style, Text, Stroke, Fill, Icon} from "ol/style"  // OpenLayers的样式类，用于定义图层的样式，包括圆形样式、基本样式、边框、填充和图标
import Polygon from "ol/geom/Polygon"
import {defineProps, withDefaults} from "vue/dist/vue";  // OpenLayers的多边形几何类，用于表示面状的地理数据import { Circle as CircleStyle, Stroke, Fill, Icon } from "ol/style"  // OpenLayers的样式类，用于定义图层的样式，包括圆形样式、基本样式、边框、填充和图标

import useNode from "../store/node";
import {storeToRefs} from "pinia";
import useFiber from "../store/fiber";
import useWDM from "../store/wdm";
import useDemand from "../store/demand";

interface MapProps {
  url: string;
  viewConfig: any;
  nodes: any;
  links: any;
  text: any;
}

const props = withDefaults(defineProps<MapProps>(), {
  url: () => "http://localhost:18082/{z}/{x}/{y}.png",
  viewConfig: () => {
    return {
      // fromLonLat是一个函数，用于将经纬度坐标转换为地图的坐标系统。
      center: fromLonLat([108.924652, 34.208527]),//地图中心点
      zoom: 5,// 缩放级别
      projection: 'EPSG:3857',
      minZoom: 6,// 最小缩放级别
      maxZoom: 12,// 最大缩放级别
      constrainResolution: true// 因为存在非整数的缩放级别，所以设置该参数为true来让每次缩放结束后自动缩放到距离最近的一个整数级别，这个必须要设置，当缩放在非整数级别时地图会糊
    }
  },
})

const demandStore =useDemand()
const {currentDemand}=storeToRefs(demandStore);
const nodeStore = useNode();
const {nodeList}=storeToRefs(nodeStore);

let map= null; // map地图
// 线图层
let pointLayer=new VectorLayer({
  source: new VectorSource(),
}); //点图层


let demandLayer=new VectorLayer({
  source: new VectorSource(),
}); //业务图层

let workRouteLayer=new VectorLayer({
  source: new VectorSource(),
}); //业务图层

let protectRouteLayer=new VectorLayer({
  source: new VectorSource(),
}); //业务图层


//监听储存在pinia中的数据
watch(nodeList, (newVal, oldVal) => {
  console.log("props.nodes",nodeList.value)
  drawPoints(nodeList.value, pointLayer,{})

}, {deep: true})


//监听储存在pinia中的数据
watch(currentDemand, (newVal, oldVal) => {
  console.log("currentDemand.value",currentDemand.value)
  // drawLines(currentDemand.value, demandLayer,{lineColor:'green',lineWidth:2})
  if (currentDemand.value?.name!=null){
    const tempDemand=demandStore.getDemandDetailByName(currentDemand.value.name)
    const tempDemandArr=[]
    console.log("tempDemand",tempDemand)
    tempDemandArr.push(tempDemand.sourceNode)
    tempDemandArr.push(tempDemand.targetNode)
    // console.log(tempDemandArr)
    // console.log(currentDemand.value.worRouteNodeList)
    drawLines(tempDemandArr, demandLayer,{lineColor:'green',lineWidth:5})
    drawLines(currentDemand.value.worRouteNodeList, workRouteLayer,{lineColor:'yellow',lineWidth:3})
    drawLines(currentDemand.value.protectRouteNodeList, protectRouteLayer,{lineColor:'red',lineWidth:3})
  }
}, {deep: true})


onMounted(() => {
  // 地图初始化
  initOLMap()
  drawPoints(nodeList.value, pointLayer,{})
  console.log("currentDemand.value",currentDemand.value)
  if (currentDemand.value?.name!=null){
    const tempDemand=demandStore.getDemandDetailByName(currentDemand.value.name)
    const tempDemandArr=[
        tempDemand.sourceNode,
        tempDemand.targetNode
    ]
    drawLines(tempDemandArr, demandLayer,{lineColor:'green',lineWidth:5})
    drawLines(currentDemand.value.worRouteNodeList, workRouteLayer,{lineColor:'yellow',lineWidth:3})
    drawLines(currentDemand.value.protectRouteNodeList, protectRouteLayer,{lineColor:'red',lineWidth:3})
  }


})


/**
 * Date:2024/3/26
 * @param nodeList
 * @param style
 */
const drawPoints = (nodeList,pointLayer, style) => {
  let pointFeatures = [];
  // map.removeLayer(pointLayer)
  pointLayer.getSource().clear();
  for (let i = 0; i < nodeList.length; i++) {
    let feature = new Feature({
      title: 'point',
      geometry: new Point(fromLonLat([nodeList[i].longitude, nodeList[i].latitude])) // 转换坐标
    })
    // 设置特征样式（Style）:
    feature.setStyle(
        new Style({
          // 使用 CircleStyle 创建一个圆形的点
          image: new CircleStyle({
            fill: new Fill({
              color: 'blue',
            }),
            radius: 5,
          }),
        })
    );
    feature.setId(nodeList[i].nodeName);
    pointFeatures.push(feature)
  }
  // pointSource = new VectorSource()
  // pointSource.addFeatures(pointFeatures)
  // 创建图层并设置源（Layer）
  // VectorLayer表示一个矢量图层，它由一系列矢量要素（Feature）组成，用于在地图上显示地理数据。
  // pointLayer = new VectorLayer()
  // pointLayer.setSource(pointSource)
  // map.addLayer(pointLayer)
  pointLayer.getSource().addFeatures(pointFeatures)
}


/**
 * Date:2024/3/26
 * @param nodeList
 * @param style
 */
const drawLines = (fiberList,layer, style) => {
  layer.getSource().clear()
  let tempGeometry=[];
  for (let i = 0; i < fiberList.length; i++) {
    tempGeometry.push(fromLonLat([fiberList[i].longitude, fiberList[i].latitude]))
  }
  let feature = new Feature({
    title: 'line',
    geometry: new LineString(tempGeometry)
  })
  // 设置特征样式（Style）:
  feature.setStyle(
      new Style({
        stroke: new Stroke({
          color: style?.lineColor ?? 'red', // 线的颜色
          width: style?.lineWidth ?? 5, // 线的宽度
        })
      })
  );
  layer.getSource().addFeature(feature)
}


/**
 * 地图初始化
 */
function initOLMap() {
  // 创造地图实例
  map = new Map({
    // 设置地图容器的ID
    target: 'olMap',
    // 定义地图的图层列表，用于显示特定的地理信息。
    layers: [
      // 高德地图
      // TileLayer表示一个瓦片图层，它由一系列瓦片（通常是图片）组成，用于在地图上显示地理数据。
      new TileLayer({
        // 设置图层的数据源为XYZ类型。XYZ是一个通用的瓦片图层源，它允许你通过URL模板来获取瓦片
        source: new XYZ({
          url: props.url,
        })
      }),
        demandLayer,
        workRouteLayer,
        protectRouteLayer,
        pointLayer,
    ],
    // 设置地图的视图参数
    // View表示地图的视图，它定义了地图的中心点、缩放级别、旋转角度等参数。
    view: new View(props.viewConfig),
    // 按住shift进行旋转
    interactions: defaultInteractions().extend([new DragRotateAndZoom()]),
    // 控件
    controls: defaults().extend([
      new FullScreen({
        className: 'myStyle2',
      }), // 全屏
      // new MousePosition(), // 显示鼠标当前位置的地图坐标
      new ScaleLine({
        className: 'myStyle',
      }),// 显示比例尺
    ])

  })

  // 事件
  map.on('moveEnd', (e: any) => {
    console.log('地图移动', e)
    // 获取当前缩放级别
    var zoomLevel = map.getView().getZoom();
    console.log('当前缩放级别：', zoomLevel);
  })
  map.on('click', (e: any) => {
    console.log('地图点击', e)
    var coordinate = e.coordinate;

    // 将投影坐标转换为经纬度坐标
    var lonLatCoordinate = toLonLat(coordinate);
    // 输出转换后的经纬度坐标
    console.log('经纬度坐标：', lonLatCoordinate);
  })

}
</script>
<style>
.myStyle {
  color: #535bf2;
  position: absolute;
  bottom: 0;
  left: 0;
}

.ol-map .ol-zoom {
  position: absolute;
  color: red;
  top: 10px;
  left: 10px;
}

#olMap {
  width: 100%;
  height: 100%;
}

/*.ol-map .ol-zoom button {*/
/*  background-color: red;*/

/*}*/

.ol-map .ol-rotate button {
  display: none;
}

.myStyle2 {
  position: absolute;
  top: 0;
  right: 0;
}

</style>